/**
 * 拖动时间轴指令
 * 用于绑定元素以实现时间轴的拖动功能，特别是在视频播放控制中调整时间范围。
 */
export default {
  bind(el, binding, vNode) {
    dragTimeAxis(el, binding, vNode);
  },
};

/**
 * 管理拖动时间轴的行为。
 * @param {HTMLElement} el - 被绑定的元素，通常是时间轴的容器。
 * @param {Object} binding - 绑定的对象，包含.syncTimeAxisFlag和.list等属性。
 * @param {Object} vNode - 虚拟节点，用于获取上下文信息。
 */
export function dragTimeAxis(el, binding, vNode) {
  const syncTimeAxisFlag = binding.value?.syncTimeAxisFlag; // 是否同步时间轴标志
  const list = binding.value.list; // 时间点列表
  const _this = vNode.context; // 上下文对象

  /* 拖动开始时的动作 */
  /* 拖动 */
  el.onmousedown = (e) => {
    e.stopPropagation(); // 阻止事件冒泡
    _this.destroyScroll(); // 销毁滚动条
    document.onmousemove = function () {
      const allTime = _this.queryEndTime - _this.queryBeginTime; // 总时间范围
      const cuurTime = _this.mouseTime - _this.queryBeginTime; // 当前时间相对于总时间的百分比
      if (cuurTime <= 0) {
        return false;
      }
      const ll = "calc(" + (cuurTime / allTime) * 100 + "% - 1px )"; // 计算当前时间相对于总时间的左边距
      el.style.left = ll;
      if (!syncTimeAxisFlag) {
        return false;
      }
      list.map((item, index) => {
        if (item.id) {
          const elements = document.querySelectorAll(
            ".time-axis .center .time:nth-child(" + (index + 1) + ") .progress"
          );
          Array.prototype.slice.call(elements).forEach(function (el2) {
            el2.classList.add("on");
            el2.style.left = ll + "px";
          });
        }
        item.leftTime = _this.mouseTime;
      });
    };
    document.onmouseup = () => {
      onmouseup(binding, vNode);
    };
  };
}

/**
 * 拖动结束时的操作。
 * @param {Object} binding - 绑定的对象。
 * @param {Object} vNode - 虚拟节点。
 */
function onmouseup(binding, vNode) {
  const _this = vNode.context; // 上下文对象
  const syncTimeAxisFlag = binding.value.syncTimeAxisFlag; // 是否同步时间轴标志

  // 移除拖动过程中的事件监听器
  document.onmousemove = null;
  document.onmouseup = null;

  setProgressLeft(_this); // 设置进度条的左边距
  _this.newScroll(); // 重新初始化滚动条

  if (binding.value.initTimeShowFlag) {
    //传入参数才调用这个方法
    initTimeShow(_this.timelineWidth);
  }

  // 根据syncTimeAxisFlag的值执行不同的逻辑
  if (!syncTimeAxisFlag) {
    let isInTime = _this.isInTimeList(_this.currentItem.times);
    if (isInTime) {
      //当前时间点有数据
      _this.$emit("setNoneVideo", _this.currentItem.sourceIndex, false);
      _this.$emit(
        "doSelectPlaybackTime2",
        _this.currentItem.id,
        _this.mouseTime,
        _this.currentItem.sourceIndex
      );
    } else {
      //无数据
      _this.$emit("setNoneVideo", _this.currentItem.sourceIndex, true);
      _this.$emit("smallVideoTime", _this.mouseTime);
    }
  } else {
    for (const element of list) {
      if (!element.id) {
        continue;
      }
      let isInTime = _this.isInTimeList(element.times);
      if (isInTime) {
        //当前时间点有数据
        _this.$emit("setNoneVideo", element.sourceIndex, false);
        _this.$emit(
          "doSelectPlaybackTime2",
          element.id,
          _this.mouseTime,
          element.sourceIndex
        );
      } else {
        //无数据
        _this.$emit("setNoneVideo", element.sourceIndex, true);
        _this.$emit("smallVideoTime", _this.mouseTime);
      }
    }
  }
}

/**
 * 初始化时间显示位置。
 * 该方法尝试根据时间轴的宽度来调整时间显示的位置，确保其可见。
 * @param {string} timelineWidth - 时间轴的宽度。
 * @param {number} count - 调用次数，用于防止无限循环。
 * @returns {boolean} 如果初始化完成返回false，否则返回true。
 */
/**
 * 初始化放大缩小位置
 * @param timelineWidth
 * @param count
 * @returns {boolean}
 */
function initTimeShow(timelineWidth, count = 0) {
  if (
    this.progressLeft === undefined ||
    timelineWidth === "100%" ||
    count > 30
  ) {
    return false;
  }

  const progressElements = document.querySelectorAll(".progress:visible");
  const visibleProgress = Array.from(progressElements).find(
    (el) => window.getComputedStyle(el).display !== "none"
  );
  const parentWidth = visibleProgress
    ? visibleProgress.parentNode.clientWidth
    : 0;

  if (timelineWidth !== parentWidth) {
    if (this.initTimeShowTiming) {
      clearTimeout(this.initTimeShowTiming);
    }
    this.initTimeShowTiming = setTimeout(() => {
      initTimeShow(timelineWidth, ++count);
    }, 100);
    return false;
  }

  const moveAfter = visibleProgress
    ? visibleProgress.getBoundingClientRect().left
    : 0;
  let moveDistance = moveAfter - this.progressLeft;

  if (moveDistance < 0) {
    moveDistance = 0;
  }

  this.toMove(
    {
      x: -moveDistance,
      y: 0,
    },
    0
  );
}

/**
 * 设置进度条的左边距。
 * @param {_this} _this - 上下文对象。
 */
function setProgressLeft(_this) {
  let progressElements = document.querySelectorAll(".progress");
  let visibleProgressElement;

  for (const element of progressElements) {
    let el = element;
    let style = window.getComputedStyle(el);
    if (style.display !== "none" && style.visibility !== "hidden") {
      visibleProgressElement = el;
      break;
    }
  }

  if (visibleProgressElement) {
    _this.progressLeft = visibleProgressElement.getBoundingClientRect().left;
  }
}
